package org.NooLab.itexx.tcp;

import java.util.Observable;
import java.util.Observer;

import org.NooLab.itexx.ITexx;
import org.NooLab.itexx.co.CoWorkerIntf;
import org.NooLab.itexx.co.CoWorkerMsgDigest;
import org.NooLab.itexx.comm.tcp.box.TcpBox;
import org.NooLab.itexx.comm.tcp.box.infra.DataReceiverIntf;
import org.NooLab.utilities.logging.PrintLog;




public class CommBox extends Observable implements Observer{
	
	
	public TcpBox tcpBox;
	
	ITexx itexx ;
	String appname;
	
	PrintLog out = new PrintLog(2,true);

	int outPort;
	int inPort;
	
	// ----------------------------------------------------
	public CommBox( ){
		// for testing purposes !!
		tcpBox = new TcpBox();
	}
	
	public CommBox( ITexx itx, String appname, int inPort, int outPort ) throws Exception{
	
		itexx = itx;
		this.appname = appname;
		
		tcpBox = new TcpBox();
		
		this.inPort  = inPort ;
		this.outPort = outPort;
		
		try{
			
			tcpBox.createReceiver( inPort, outPort, this, "") ;
			if (outPort>1000){
				tcpBox.createSender(outPort, inPort, "") ;
			}
			
			tcpBox.addObserver(this);
		}catch(Exception e){
			e.printStackTrace();
		}
		
		if (tcpBox.getTcpReceiver()==null){
			throw(new Exception("Communication server for <"+appname+"> failed to start, no listening at port <"+inPort+"> ... "));
		} 
		
	}
	// ----------------------------------------------------

	@Override
	public void update(Observable senderObj, Object msgObj) {
		 
		out.print(4, "CommBox in <iTexx> received a Tcp message from <"+(senderObj.getClass().getSimpleName())+">...");

		if (inPort == CoWorkerIntf._mainServerPort){

			// decode message in dedicated routine
			new CoWorkerMsgDigest( itexx, inPort, msgObj) ;
		}
		
		
	}

	public ITexx getItexx() {
		return itexx;
	}

	public void setItexx(ITexx itexx) {
		this.itexx = itexx;
	}

	public int getOutPort() {
		return outPort;
	}

	public void setOutPort(int outPort) {
		this.outPort = outPort;
	}

	public int getInPort() {
		return inPort;
	}

	public void setInPort(int inPort) {
		this.inPort = inPort;
	}

	public TcpBox getTcpBox() {
		return tcpBox;
	}

	public boolean checkPortAvailability(int testPort, int dummyReceiverPort) {
		
		boolean result=false;
		
		
		try{
			
			DataReceiverIntf receiver = tcpBox.createReceiver(testPort, dummyReceiverPort, this, "");
			
			
			// if it is available, we close it here again, because we need it elsewhere
			if (receiver != null){
				receiver.closePort() ;
				result = true;
			}
			receiver = null;
			
		}catch(Exception e){
			e.printStackTrace();
		}
		
		return result;
	}
	
}	
